package com.sam.im.heiqun.uis.fragments;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.sam.im.heiqun.R;
import com.sam.im.heiqun.constant.Constant;
import com.sam.im.heiqun.entities.GroupFriendEntivity;
import com.sam.im.heiqun.entities.ImFriendEntivity;
import com.sam.im.heiqun.entities.ImGroupEntivity;
import com.sam.im.heiqun.entities.ReadyEntivity;
import com.sam.im.heiqun.entities.SearchUserEntity;
import com.sam.im.heiqun.entities.UpdateGroupEntivity;
import com.sam.im.heiqun.entities.UserEntivity;
import com.sam.im.heiqun.entities.event.EventCollectGroup;
import com.sam.im.heiqun.nets.PGService;
import com.sam.im.heiqun.uis.activities.ChatGroupActivity;
import com.sam.im.heiqun.uis.activities.SeachFriendsActivity;
import com.sam.im.heiqun.uis.activities.SeachGroupActivity;
import com.sam.im.heiqun.uis.activities.SelecteLocalFriendActivity;
import com.sam.im.heiqun.utils.RxJavaUtil;
import com.sam.im.heiqun.utils.ToolsUtils;
import com.yuyh.library.nets.callbacks.AbsAPICallback;
import com.yuyh.library.nets.exceptions.ApiException;
import com.yuyh.library.uis.fragments.BaseFragment;
import com.yuyh.library.utils.DividerItemDecorationUtils;
import com.yuyh.library.utils.EventBusType;
import com.yuyh.library.utils.GlideUtils;
import com.zq.view.recyclerview.adapter.OnItemClickListener;
import com.zq.view.recyclerview.adapter.cell.Cell;
import com.zq.view.recyclerview.adapter.cell.CellAdapter;
import com.zq.view.recyclerview.adapter.cell.DataBinder;
import com.zq.view.recyclerview.adapter.cell.MultiCell;
import com.zq.view.recyclerview.adapter.cell.collapse.CollapsibleCell;
import com.zq.view.recyclerview.viewholder.RVViewHolder;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Callable;

import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Cancellable;
import io.reactivex.functions.Function;

/**
 * Created by Joe on 2017/1/2.
 */

public class GroupFragment extends BaseFragment implements OnItemClickListener {

    private static final String TAG = GroupFragment.class.getSimpleName();

    @BindView(R.id.group_list)
    RecyclerView groupList;
    @BindView(R.id.search_edit)
    EditText searchEdit;

    @BindView(R.id.no_group_found_tx_id)
    LinearLayout no_group_found_tx;
    @BindView(R.id.groud_found_tx)
    TextView groud_found_tx;

    @BindView(R.id.group_locality_not_found_id)
    TextView group_locality_not_found_tx;
    private CellAdapter mGroupAdapter;
    private CellAdapter mSearchAdapter;
    private int richScanCode = 1;

    PGService mPgService;
    String value;//输入框的值
    private UserEntivity userEntivity;
    private List<Object> expandGroups = new ArrayList<>();

    @Override
    public int getContentViewId() {
        return R.layout.fragment_groud;
    }

    @Override
    public void init(Bundle savedInstanceState) {
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);//订阅
        }
        mPgService = PGService.getInstance();
        userEntivity = ToolsUtils.getUser();
        groupList.setLayoutManager(new LinearLayoutManager(getActivity()));
        mGroupAdapter = new CellAdapter(getActivity());
        mGroupAdapter.setOnItemClickListener(this);
        groupList.setAdapter(mGroupAdapter);
        groupList.addItemDecoration(new DividerItemDecorationUtils(getActivity(), LinearLayoutManager.HORIZONTAL, 1, getResources().getColor(R.color.black_divider)));

        mSearchAdapter = new CellAdapter(getActivity());
        mSearchAdapter.setOnItemClickListener(this);
        initSearch();

        loadAllGroups(true);
    }

    private void initSearch() {


        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(final ObservableEmitter<String> e) throws Exception {

                searchEdit.setOnEditorActionListener(new TextView.OnEditorActionListener() {
                    @Override
                    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                        value = v.getText().toString();
                        if (!TextUtils.isEmpty(value) && actionId == EditorInfo.IME_ACTION_SEARCH) {
                            e.onNext(value);
                        }
                        return false;
                    }
                });
                e.setCancellable(new Cancellable() {
                    @Override
                    public void cancel() throws Exception {
                        searchEdit.setOnEditorActionListener(null);
                    }
                });
            }
        }).switchMap(new Function<String, ObservableSource<List<ImGroupEntivity>>>() {
            @Override
            public ObservableSource<List<ImGroupEntivity>> apply(final String s) throws Exception {

                return Observable.fromCallable(new Callable<List<ImGroupEntivity>>() {
                    @Override
                    public List<ImGroupEntivity> call() throws Exception {
                        return ImGroupEntivity.find(ImGroupEntivity.class, "name like ? or descriptions like ? or id like ?", "%" + s + "%", "%" + s + "%", "%" + s + "%");
                    }
                }).compose(RxJavaUtil.<List<ImGroupEntivity>>applySchedules());
            }
        }).subscribe(new AbsAPICallback<List<ImGroupEntivity>>() {
            @Override
            public void onNext(List<ImGroupEntivity> imGroupEntivities) {
                if(imGroupEntivities.size() > 0){
                    //no_group_found_tx.setVisibility(View.GONE);

                    no_group_found_tx.setVisibility(View.GONE);
                    groupList.setVisibility(View.VISIBLE);
                    mSearchAdapter.setDataList(MultiCell.convert2(R.layout.item_group_list, imGroupEntivities, imGroupEntivityDataBinder));
                    groupList.setAdapter(mSearchAdapter);

                } else {//查询没有结果
                    Log.i("info","走了这里没有查询到结果");
                    no_group_found_tx.setVisibility(View.VISIBLE);
                    group_locality_not_found_tx.setText("本地未查询到，网络查找");
                    group_locality_not_found_tx.setVisibility(View.VISIBLE);
                    groud_found_tx.setText(value);
                    groud_found_tx.setVisibility(View.VISIBLE);
                    groupList.setVisibility(View.GONE);

                }
            }
            @Override
            protected void onResultError(ApiException ex) {

            }
        });

        searchEdit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                int length = s.length();
                if (length <= 0) {
                    groupList.setVisibility(View.VISIBLE);
                    no_group_found_tx.setVisibility(View.GONE);
                    groupList.setAdapter(mGroupAdapter);
                }
            }
        });
    }

//    GlideUtils.loadHeadGroupCircularImage(context, mGroupEntivities.get(position).getHeadUrl(), holder.img);
//        holder.name.setText(mGroupEntivities.get(position).getName());

    @Override
    public void onResume() {
        super.onResume();
        loadAllGroups(false);
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void showNum(Integer code) {
//
        if (code == EventBusType.REFRESH_GROUP_USER_MANAGER) {
            loadAllGroups(false);
        }
    }


    @Subscribe(threadMode = ThreadMode.MAIN) //在ui线程执行
    public void onEventMainThread(String event) {
        if (Constant.BLACK_BROADCAST_ADD_GROUP_FOUND_REFRESH.equals(event)) {
            loadAllGroups(false);
        }
//        if (Constant.FRAGMENT_FRIEND_REFRESH_GROUP.equals(event)) {
//            mGroupAdapter.refresh(mGroupEntivities);
//        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN) //在ui线程执行
    public void onUpdateGroupName(UpdateGroupEntivity event) {
        if (event.getCode() == 2001) {
            loadAllGroups(false);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN) //在ui线程执行
    public void onUpdateGroupName(EventCollectGroup event) {
        loadAllGroups(false);
    }

    @Subscribe(threadMode = ThreadMode.MAIN) //在ui线程执行
    public void onReadyEntivity(ReadyEntivity readyEntivity) {

        if (readyEntivity.getGroupsInfo() == null) {
            return;
        }
        Observable.just(readyEntivity.getGroupsInfo())
                .map(new Function<List<ImGroupEntivity>, List<Cell>>() {
                    @Override
                    public List<Cell> apply(List<ImGroupEntivity> imGroupEntivities) throws Exception {
                        return makeGroups(imGroupEntivities);
                    }
                })
                .compose(RxJavaUtil.<List<Cell>>applySchedules())
                .compose(this.<List<Cell>>bindLifeCycle())
                .subscribe(new AbsAPICallback<List<Cell>>() {
                    @Override
                    public void onNext(List<Cell> cellList) {
                        mGroupAdapter.setDataList(cellList);
                    }

                    @Override
                    protected void onResultError(ApiException ex) {

                    }
                });
    }

    private void loadAllGroups(final boolean expandFirst) {

        Observable.fromCallable(new Callable<List<ImGroupEntivity>>() {

            @Override
            public List<ImGroupEntivity> call() throws Exception {

                return ImGroupEntivity.find(ImGroupEntivity.class, "currentid = ?", userEntivity.getId() + "");

            }
        })
                .compose(RxJavaUtil.<List<ImGroupEntivity>>applySchedules())
                .compose(this.<List<ImGroupEntivity>>bindLifeCycle())
                .flatMap(new Function<List<ImGroupEntivity>, ObservableSource<List<Cell>>>() {
                    @Override
                    public ObservableSource<List<Cell>> apply(List<ImGroupEntivity> imGroupEntivities) throws Exception {

                        final int groupCount = imGroupEntivities.size();

                        if (groupCount <= 0) {
                            return Observable.just(makeGroups(null));
                        }

                        return Observable.fromIterable(imGroupEntivities).flatMap(new Function<ImGroupEntivity, ObservableSource<ImGroupEntivity>>() {
                            @Override
                            public ObservableSource<ImGroupEntivity> apply(final ImGroupEntivity imGroupEntivity) throws Exception {

                                final Long groupId = imGroupEntivity.getId();
                                if (groupId == null) {
                                    return Observable.empty();
                                }

                                UserEntivity userEntivity = ToolsUtils.getUser();
                                if (userEntivity == null) {
                                    return Observable.empty();
                                }
                                Long userId = userEntivity.getId();
                                if (userId == null) {
                                    return Observable.empty();
                                }

                                return PGService.getInstance().getGroupMember(String.valueOf(groupId), String.valueOf(userId))
                                        .map(new Function<SearchUserEntity, List<ImFriendEntivity>>() {
                                            @Override
                                            public List<ImFriendEntivity> apply(SearchUserEntity searchUserEntity) throws Exception {
                                                List<ImFriendEntivity> friendEntivities = searchUserEntity.getInfo();
                                                GroupFriendEntivity.deleteAll(GroupFriendEntivity.class, "belong_group_id = ?", String.valueOf(groupId));
                                                ToolsUtils.saveGroupUserS(friendEntivities, groupId);
                                                return friendEntivities;
                                            }
                                        })
                                        .map(new Function<List<ImFriendEntivity>, ImGroupEntivity>() {
                                            @Override
                                            public ImGroupEntivity apply(List<ImFriendEntivity> imFriendEntivities) throws Exception {
                                                return imGroupEntivity;
                                            }
                                        });
                            }
                        }).buffer(groupCount).map(new Function<List<ImGroupEntivity>, List<Cell>>() {
                            @Override
                            public List<Cell> apply(List<ImGroupEntivity> lists) throws Exception {

                                Collections.sort(lists, new Comparator<ImGroupEntivity>() {
                                    @Override
                                    public int compare(ImGroupEntivity o1, ImGroupEntivity o2) {
                                        String name1 = o1.getName();
                                        String name2 = o2.getName();
                                        if (name1 == null || name2 == null) {
                                            return 0;
                                        }
                                        return name1.compareTo(name2);
                                    }
                                });
                                List<Cell> cellList = makeGroups(lists);
                                if (expandFirst) {
                                    Cell cell = cellList.get(0);
                                    if (cell instanceof CollapsibleCell) {
                                        Object data = ((CollapsibleCell) cell).getData();
                                        if (!expandGroups.contains(data)) {
                                            expandGroups.add(data);
                                        }
                                    }
                                }
                                return cellList;
                            }
                        });
                    }
                })
                .subscribe(new AbsAPICallback<List<Cell>>() {
                    @Override
                    public void onNext(List<Cell> cellList) {
                        mGroupAdapter.setDataList(cellList);
                        for (Object expandGroup : expandGroups) {

                            for (Cell cell : cellList) {

                                if (cell instanceof CollapsibleCell) {

                                    if (expandGroup.equals(((CollapsibleCell) cell).getData())) {
                                        ((CollapsibleCell) cell).expand(mGroupAdapter);
                                    }
                                }
                            }
                        }
                    }

                    @Override
                    protected void onResultError(ApiException ex) {

                    }
                });
    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == richScanCode) {//二维码扫描

        }
    }

    @Override
    public void onDestroyView() {
        EventBus.getDefault().unregister(this);
        super.onDestroyView();
    }

    @Override
    public void onItemClick(RecyclerView.ViewHolder viewHolder, int i) {

        CellAdapter adapter = ((CellAdapter) groupList.getAdapter());

        Cell cell = adapter.getDataAt(i);
        //((rvViewHolder)).viewHolder;
        if (cell instanceof CollapsibleCell) {

            CollapsibleCell collapsibleCell = (CollapsibleCell) cell;
            if (collapsibleCell.isCollapsible()) {

                collapsibleCell.expand(adapter);
                expandGroups.add(collapsibleCell.getData());
            } else {
                collapsibleCell.collapse(adapter);

                expandGroups.remove(collapsibleCell.getData());
            }
            collapsibleCell.notifyCellChange();
        } else if (cell instanceof MultiCell) {

            Object data = ((MultiCell) cell).getData();
            if (data instanceof ImGroupEntivity) {

                ImGroupEntivity imGroupEntivity = (ImGroupEntivity) data;
                Bundle bundle = new Bundle();
                bundle.putSerializable("groupSeri", imGroupEntivity);
                bundle.putLong("groupid", imGroupEntivity.getId());
                startActivity(ChatGroupActivity.class, bundle);
            }
        }
    }

    @NonNull
    private List<Cell> makeGroups(@Nullable List<ImGroupEntivity> imGroupEntivities) {

        List<Cell> groupICreateCells = new ArrayList<>();
        List<Cell> groupIManageCells = new ArrayList<>();
        List<Cell> groupIJoinCells = new ArrayList<>();
        List<Cell> groupICollectCells = new ArrayList<>();

        List<Cell> groupsCells = new ArrayList<>();
        CollapsibleCell<Integer> iCreateTitleCell = new CollapsibleCell<>(R.layout.item_group_title, R.string.group_i_create, null, groupICreateCells);
        iCreateTitleCell.setDataBinder(new GroupTitleDataBinder(iCreateTitleCell));
        groupsCells.add(iCreateTitleCell);
        CollapsibleCell<Integer> iManageTitleCell = new CollapsibleCell<>(R.layout.item_group_title, R.string.group_i_manage, null, groupIManageCells);
        iManageTitleCell.setDataBinder(new GroupTitleDataBinder(iManageTitleCell));
        groupsCells.add(iManageTitleCell);
        CollapsibleCell<Integer> iJoinTitleCell = new CollapsibleCell<>(R.layout.item_group_title, R.string.group_i_join, null, groupIJoinCells);
        iJoinTitleCell.setDataBinder(new GroupTitleDataBinder(iJoinTitleCell));
        groupsCells.add(iJoinTitleCell);
        CollapsibleCell<Integer> iCollectTitleCell = new CollapsibleCell<>(R.layout.item_group_title, R.string.group_i_collect, null, groupICollectCells);
        iCollectTitleCell.setDataBinder(new GroupTitleDataBinder(iCollectTitleCell));
        groupsCells.add(iCollectTitleCell);

        UserEntivity userEntivity = ToolsUtils.getUser();
        if (userEntivity == null) {
            return groupsCells;
        }
        if (imGroupEntivities == null || imGroupEntivities.isEmpty()) {
            return groupsCells;
        }
        Long userId = userEntivity.getId();
        for (ImGroupEntivity imGroupEntivity : imGroupEntivities) {

            Long createrId = imGroupEntivity.getCreaterId();
            boolean isCreator = createrId != null && createrId.equals(userId);

            if (isCreator) {
                //添加我创建的群
                groupICreateCells.add(MultiCell.convert(R.layout.item_group_list, imGroupEntivity, imGroupEntivityDataBinder));
            }

            if ("1".equals(imGroupEntivity.getFavorite())) {
                //如果是收藏的群
                groupICollectCells.add(MultiCell.convert(R.layout.item_group_list, imGroupEntivity, imGroupEntivityDataBinder));
            }

            Long groupId = imGroupEntivity.getId();
            if (groupId == null) {
                continue;
            }

            //查询我在这个群的成员对象
            List<GroupFriendEntivity> friendEntivities = ToolsUtils.groupUserRemoval(GroupFriendEntivity.find(GroupFriendEntivity.class,
                    "belong_group_id=? and uid = ?",
                    String.valueOf(groupId),
                    String.valueOf(userId)));

            //获取到自己加入的也就是自己是普通成员的
            if (friendEntivities.size() > 0) {
                GroupFriendEntivity groupFriendEntivity = friendEntivities.get(0);

                if (!isCreator && "1".equals(groupFriendEntivity.getRole()) || "3".equals(groupFriendEntivity.getRole())) {
                    groupIJoinCells.add(MultiCell.convert(R.layout.item_group_list, imGroupEntivity, imGroupEntivityDataBinder));
                }
                //这是获取到所有群包括自己管理的跟创建的
           /* if (friendEntivities != null && !friendEntivities.isEmpty()) {

                groupIJoinCells.add(MultiCell.convert(R.layout.item_group_list, imGroupEntivity, imGroupEntivityDataBinder));

                GroupFriendEntivity groupFriendEntivity = friendEntivities.get(0);*/
                //如果是群主或管理员并且不是创建者
                if (!isCreator && "1".equals(groupFriendEntivity.getRole()) || "2".equals(groupFriendEntivity.getRole())) {
                    groupIManageCells.add(MultiCell.convert(R.layout.item_group_list, imGroupEntivity, imGroupEntivityDataBinder));
                    //}
                }
            }

        }
        return groupsCells;
    }


    DataBinder<ImGroupEntivity> imGroupEntivityDataBinder = new DataBinder<ImGroupEntivity>() {
        @Override
        public void bindData(RVViewHolder rvViewHolder, ImGroupEntivity groupEntivity) {

            Context context = rvViewHolder.getView().getContext();
            GlideUtils.loadHeadGroupCircularImage(context, groupEntivity.getHeadUrl(), (ImageView) rvViewHolder.getView(R.id.img));
            rvViewHolder.setText(R.id.name, groupEntivity.getName());
            String level = groupEntivity.getLevel();
            if ("1".equals(level)) {
                rvViewHolder.setVisibility(R.id.iv_group_level, View.VISIBLE);
                rvViewHolder.setImageResource(R.id.iv_group_level, R.drawable.group_level_1);
            } else if ("2".equals(level)) {
                rvViewHolder.setVisibility(R.id.iv_group_level, View.VISIBLE);
                rvViewHolder.setImageResource(R.id.iv_group_level, R.drawable.group_level_2);
            } else if ("3".equals(level)) {
                rvViewHolder.setVisibility(R.id.iv_group_level, View.VISIBLE);
                rvViewHolder.setImageResource(R.id.iv_group_level, R.drawable.group_level_3);
            } else if ("4".equals(level)) {
                rvViewHolder.setVisibility(R.id.iv_group_level, View.VISIBLE);
                rvViewHolder.setImageResource(R.id.iv_group_level, R.drawable.group_level_4);
            } else {
                rvViewHolder.setVisibility(R.id.iv_group_level, View.GONE);
            }
        }
    };

    class GroupTitleDataBinder implements DataBinder<Integer> {

        private CollapsibleCell collapsibleCell;

        public GroupTitleDataBinder(CollapsibleCell collapsibleCell) {
            this.collapsibleCell = collapsibleCell;
        }

        @Override
        public void bindData(RVViewHolder rvViewHolder, Integer titleRes) {
            rvViewHolder.setText(R.id.tv_title, titleRes);
            rvViewHolder.getView(R.id.im_id_jiantou).setSelected(!collapsibleCell.isCollapsible());
        }
    }

    @OnClick(R.id.txt_clean)
    public void onViewClicked() {
        searchEdit.getText().clear();
    }
    @OnClick({R.id.no_group_found_tx_id})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.no_group_found_tx_id: {//搜索好友
                Intent intent=new Intent();
                intent.putExtra("value",value);
                intent.setClass(getContext(), SeachGroupActivity.class);
                startActivity(intent);
                break;
            }
        }
    }
}
